﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class bestellen_Afrekenen : System.Web.UI.Page
{
    MovieManager mm;
    TicketManager tm;
    PlanningManager pm;
    VoucherManager vm;
    ReservationManager rm;
    PaymentManager pym = new PaymentManager();
    EmailManager em = new EmailManager();
    DateTimeConverter dtc = new DateTimeConverter();

    film currentMovie;
    planning currentPlanning;
    bestelling currentOrder;
    account currentAccount;

    double totalCost;
    double discount;
    double subscriptionDiscount;

    protected void Page_Load(object sender, EventArgs e)
    {
        if (Master.getUser() == null)
        {
            Response.Redirect("~/Login.aspx?redirect=bestellen/Afrekenen.aspx");
        }

        currentAccount = Master.getUser();

        mm = new MovieManager((debioscoopEntities)Session["db"]);
        tm = new TicketManager((debioscoopEntities)Session["db"]);
        vm = new VoucherManager((debioscoopEntities)Session["db"]);
        pm = new PlanningManager((debioscoopEntities)Session["db"]);
        rm = new ReservationManager((debioscoopEntities)Session["db"]);

        if (Session["order"] != null)
        {
            currentOrder = (bestelling)Session["order"];

            currentPlanning = currentOrder.planning;
            currentMovie = currentPlanning.film;

            //Fill controls with info from the film object
            movieImg.ImageUrl = currentMovie.url;
            movTitle.Text = currentMovie.naam;
            movGenres.Text = mm.getGenreInString(currentMovie, ",", Master.tl.getCurrentLanguage());
            movLength.Text = currentMovie.duur.ToString();
            movProducer.Text = currentMovie.reggiseur;
            movType.Text = ((bool)currentPlanning.dried ? "3D" : "OV");
            movSeatsAvailable.Text = pm.getAvailableSeats(currentPlanning).ToString();
            movTime.Text = dtc.getTimeforMovie(currentPlanning.tijd);

            //Repeater gets list of movie rated
            movieRatedRepeater.DataSource = currentMovie.kijkwijzers;
            movieRatedRepeater.DataBind();

            //Get every kind of ticket from the order
            List<String> ticketNames = new List<string>();
            foreach (kaartje ticket in currentOrder.kaartjes)
            {
                if (!ticketNames.Contains(ticket.kaart_soort.kaart_soort_naam))
                {
                    ticketNames.Add(ticket.kaart_soort.kaart_soort_naam);
                }
            }

            ticketsRepeater.DataSource = ticketNames;
            ticketsRepeater.DataBind();

            foreach (kaartje ticket in currentOrder.kaartjes)
            {
                if (ticket.abbonement != null)
                {
                    if (ticket.abbonement.kortingpercentage > 0)
                    {
                        subscriptionDiscount += (ticket.prijs * ((double)ticket.abbonement.kortingpercentage / 100));
                    }
                    else
                    {
                        subscriptionDiscount += (ticket.prijs - (double)ticket.abbonement.kortingpercentage);
                    }
                }
            }

            //Buttons
            if (currentOrder.soort.Equals("koop"))
            {
                iDeal.Visible = true;
            }
            else
            {
                reservering.Visible = true;
                vouchers.Visible = false;
            }

            //Set price and amount of glasses if available
            if (currentOrder.brillen > 0)
            {
                amountGlasses.Text = currentOrder.brillen.ToString();
                glassesLabel.Text = "3D bril";
                int glassesPrice = 1;
                priceGlasses.Text = glassesPrice.ToString("#.00");

                //add glasses cost to totalCost
                totalCost = totalCost + (Double)(glassesPrice * currentOrder.brillen);
            }
            else
            {
                //Make glasses table row invisible
                glassesTR.Visible = false;
            }

            //Check if discount is available
            if (!priceVoucher.Text.Equals(""))
            {
                discount = double.Parse(priceVoucher.Text);
            }
            else
            {
                //Make voucher table row invisible
                voucherTR.Visible = false;
            }

            //Check if subscription discount is available
            if (subscriptionDiscount > 0)
            {
                subscriptionName.Text = "Abbonement Korting";
                priceSubscription.Text = subscriptionDiscount.ToString("0.00");
                subscriptionTR.Visible = true;
            }

            //Check if voucher is inserted
            if (!String.IsNullOrEmpty(Request.Form["voucherID"]))
            {
                int voucherID = int.Parse(Request.Form["voucherID"]);
                if (vm.getVoucher(voucherID) != null)
                {
                    //Get discount from voucher and remove it from the voucher
                    discount = discount + vm.getDiscount(voucherID, (totalCost - discount));
                    nameVoucher.Text = "Korting";
                    priceVoucher.Text = discount.ToString("0.00");
                    voucherTR.Visible = true;
                    lblNotification.Text = "- " + Master.tl.getTranslation("ntfVoucherAccept") + "!";
                }
                else
                {
                    lblNotification.Text = "- " + Master.tl.getTranslation("ntfNoVoucher") + " " + voucherID.ToString() + ".";
                }
            }

            //Substract the subscription discount (if available) from the total cost
            totalCost = totalCost - subscriptionDiscount;

            //Subtract the discount (if available) from the total cost
            totalCost = totalCost - discount;

            //Set total price to the label
            total.Text = totalCost.ToString("0.00");
            currentOrder.totaal_bedrag = totalCost;
        }
        else
        {
            Response.Redirect("~/");
        }
    }

    protected void tickets_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
        {
            string ticketName = e.Item.DataItem.ToString();
            int amount = currentOrder.kaartjes.Where(k => k.kaart_soort.kaart_soort_naam.Equals(ticketName)).Count();
            double price = currentOrder.planning.film.prijs;
            kaart_soort currentTicket = tm.getTicketByName(ticketName);

            //Check if there is a precentage discount or fixed ammount
            if (currentTicket.kortingpercentage != 0)
            {
                price = price * ((100 - (double)currentTicket.kortingpercentage) / 100);
            }
            else
            {
                price = price - (double)currentTicket.kortingbedrag;
            }

            foreach (kaartje ticket in currentOrder.kaartjes)
            {
                if (ticket.kaart_soort.kaart_soort_naam.Equals(ticketName))
                {
                    ticket.prijs = price;
                }
            }

            //Get Labels
            Label labelTicketName = (Label)e.Item.FindControl("ticketName");
            Label labelAmount = (Label)e.Item.FindControl("amount");
            Label labelPrice = (Label)e.Item.FindControl("price");

            //Set Labels
            if (Master.tl.getCurrentLanguage().Equals("english"))
            {
                labelTicketName.Text = currentTicket.kaart_soort_naam_en;
            }
            else
            {
                labelTicketName.Text = currentTicket.kaart_soort_naam;
            }
            
            labelAmount.Text = amount.ToString();
            labelPrice.Text = price.ToString("#.00");

            totalCost += amount * price;
        }
    }

    //create pdf for each ticket
    public List<String> createTickets()
    {
        List<String> ticketURL = new List<string>();

        foreach (kaartje ticket in currentOrder.kaartjes)
        {
            OutputManager outputManager = new OutputManager("bestellen/Ticket.rdlc");

            //set parameters for ticket
            outputManager.addParameter("movieName", currentMovie.naam);
            outputManager.addParameter("date", currentOrder.datum.ToShortDateString());
            outputManager.addParameter("time", dtc.getTimeforMovie(currentOrder.planning.tijd));
            outputManager.addParameter("price", ticket.prijs.ToString("0.00"));
            outputManager.addParameter("room", currentPlanning.zaalzaalnummer.ToString());
            outputManager.addParameter("orderNr", currentOrder.bestelling_id.ToString());
            outputManager.addParameter("cinemaName", currentPlanning.zaal.bioscoop.naam);
            outputManager.addParameter("imageFile", Server.MapPath("~") + currentMovie.url.Replace("/debioscoop", "").Replace("/", "\\"));

            String rowValue = "N/A";
            String seatValue = "N/A";

            if (currentMovie.stoelen_kiezen == true)
            {
                rowValue = ticket.rijnummer.ToString();
                seatValue = ticket.zittingnummer.ToString();
            }

            outputManager.addParameter("row", rowValue);
            outputManager.addParameter("seat", seatValue);

            outputManager.createTicket(Server.MapPath("~") + "\\touchscreen\\Tickets\\", ".pdf",
                currentOrder.datum.ToShortDateString() + "-" + currentOrder.bestelling_id.ToString() + "-" + ticket.kaartjeid.ToString());
            
            ticketURL.Add(Server.MapPath("~") + "\\touchscreen\\Tickets\\" + currentOrder.datum.ToShortDateString() + "-" + currentOrder.bestelling_id.ToString() + "-" + ticket.kaartjeid.ToString() + ".pdf");
        }
        return ticketURL;
    }

    public void createOrder()
    {
        rm.addReservation(currentOrder);

        //Update subscriptions with amount
        if(currentAccount.abbonement != null)
        {
            if(currentAccount.account_abbonement.aantal > 0)
            {
                int usedAmount = currentOrder.kaartjes.Where(k => k.abbonementabbonement_id > 0).Count();
                currentAccount.account_abbonement.aantal = currentAccount.account_abbonement.aantal - usedAmount;
                debioscoopEntities db = (debioscoopEntities)Session["db"];
                db.SaveChanges();
            }
        }

        ListDictionary parameters = new ListDictionary();
        parameters.Add("<%bestelling_id%>", currentOrder.bestelling_id.ToString());
        //TODO: Use account entity
        parameters.Add("<%klant%>", currentAccount.voornaam + " " + currentAccount.achternaam);

        //PDF attachements
        if (currentOrder.soort.Equals("koop"))
        {
            em.setPDFAttachments(createTickets());
        }

        String content = Master.tl.getTranslation("mailDear") + " <%klant%>, <br /><br /> <b>" + Master.tl.getTranslation("mailOrdernumber") + ": </b><%bestelling_id%> <br /> " + Master.tl.getTranslation("mailInstructions") + ".  <br /><br /> " + Master.tl.getTranslation("mailThanks") + ". <br /> De Bioscoop";
        //TODO: use account entity
        em.sendEmail(currentAccount.email, "Uw bestelling bij DeBioscoop", parameters, content);

        iDeal.Visible = false;
        reservering.Visible = false;
        back.Visible = true;
        previous.Visible = false;

        lblNotification.Text = "- " + Master.tl.getTranslation("ntfOrderSucces") +  ".";
        vouchers.Visible = false;

        Session["order"] = null;
    }

    protected void iDeal_Click(object sender, EventArgs e)
    {
        //TODO: api
        if (pym.CheckPIN(totalCost, 1234))
        {
            currentOrder.betaald = true;
            createOrder();
        }
        else
        {
            lblNotification.Text = "- Er is een fout opgetreden tijdens het betalen. Probeer het opnieuw.";
        }
    }

    protected void reservering_Click(object sender, EventArgs e)
    {
        createOrder();
    }

    protected void back_Click(object sender, EventArgs e)
    {
        Response.Redirect("~/");
    }

    protected void previous_Click(object sender, EventArgs e)
    {
        foreach (kaartje ticket in currentOrder.kaartjes)
        {
            ticket.rijnummer = 0;
            ticket.zittingnummer = 0;
        }

        Response.Redirect("~/bestellen/stoelkeuze.aspx");
    }
}